﻿using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
using System.Linq.Expressions;
using DataAccess;
using QuanLyKhachSan.Validation;

namespace QuanLyKhachSan
{
    public class HoaDonDichVuManager : IValidator<HoaDonDichVu>
    {
        public ValidateResult Validate(HoaDonDichVu obj)
        {
            var validateResult = new ValidateResult();
            if (obj.TenHoaDon.Trim().Equals(""))
            {
                validateResult.Message.Add("Tên hóa đơn bắt buộc phải nhập");
            }
            if (obj.NgaySuDung > DateTime.UtcNow)
            {
                validateResult.Message.Add("Ngày sử dụng không hợp lệ");
            }
            if (obj.NgayThanhToan < obj.NgaySuDung)
            {
                validateResult.Message.Add("Ngày thanh toán không hợp lệ");
            }
            if (obj.NgaySuDung > obj.NgayThanhToan)
            {
                validateResult.Message.Add("Ngày thanh toán phải lớn hơn hoặc bằng ngày Sd");
            }
            if (obj.ThanhTien <= 0)
            {
                validateResult.Message.Add("Hóa đơn này chưa có dịch vụ nào");
            }
            return validateResult;
        }

        public ActionResult Delete(int orderId)
        {
            var actionResult = new ActionResult();
            try
            {
                using (var context = new QLKhachSanContext())
                {
                    using (DbContextTransaction dbTransaction = context.Database.BeginTransaction())
                    {
                        try
                        {
                            context.Database.ExecuteSqlCommand(@"delete HoaDonDichVu where MaHoaDonDV =" + orderId);
                            dbTransaction.Commit();
                        }
                        catch (Exception ex)
                        {
                            dbTransaction.Rollback();
                            actionResult.Exceptions.Add(ex);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                actionResult.Exceptions.Add(ex);
            }
            return actionResult;
        }

        public ActionResult XoaKhiRangBuoc(int orderId)
        {
            var actionResult = new ActionResult();
            try
            {
                using (var context = new QLKhachSanContext())
                {
                    using (DbContextTransaction dbTransaction = context.Database.BeginTransaction())
                    {
                        try
                        {
                            context.Database.ExecuteSqlCommand(@"delete ChiTietHoaDonDichVu where MaHoaDonDV =" +
                                                               orderId);
                            context.Database.ExecuteSqlCommand(@"delete HoaDonDichVu where MaHoaDonDV =" + orderId);
                            dbTransaction.Commit();
                        }
                        catch (Exception ex)
                        {
                            dbTransaction.Rollback();
                            actionResult.Exceptions.Add(ex);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                actionResult.Exceptions.Add(ex);
            }
            return actionResult;
        }

        public static ActionResult UpdateMoney(int orderId)
        {
            var actionResult = new ActionResult();
            try
            {
                using (var context = new QLKhachSanContext())
                {
                    var order =
                        context.ChiTietHoaDonDichVus.Where(ct => ct.MaHoaDonDV.Equals(orderId))
                            .ToList<ChiTietHoaDonDichVu>();
                    decimal thanhTien = 0;
                    foreach (ChiTietHoaDonDichVu item in order)
                    {
                        double giamGia = 0;
                        if (item.DichVu.GiamGia > 0)
                            giamGia = (item.SoLuong*Convert.ToDouble(item.DichVu.Gia))*(double) item.DichVu.GiamGia/100;

                        thanhTien += (item.SoLuong*item.DichVu.Gia) - Convert.ToDecimal(giamGia);
                    }
                    var hdDv = context.HoaDonDichVus.Single(sv => sv.MaHoaDonDV.Equals(orderId));
                    hdDv.ThanhTien = thanhTien;
                    if (hdDv.ThanhTien <= 0)
                        context.HoaDonDichVus.Remove(hdDv);
                    else
                        context.HoaDonDichVus.AddOrUpdate<HoaDonDichVu>(hdDv);
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                actionResult.Exceptions.Add(ex);
            }
            return actionResult;
        }

        public ActionResult Delete(HoaDonDichVu order)
        {
            return Delete(order.MaHoaDonDV);
        }

        public ActionResult InsertOrUpdate(HoaDonDichVu obj)
        {
            var acResult = new ActionResult();
            using (var context = new QLKhachSanContext())
            {
                try
                {
                    context.HoaDonDichVus.AddOrUpdate(obj);
                    context.SaveChanges();
                }
                catch (Exception ex)
                {
                    acResult.Exceptions.Add(ex);
                }
            }
            return acResult;
        }

        public ActionResult Add(HoaDonDichVu obj)
        {
            var acResultl = new ActionResult();
            try
            {
                using (var context = new QLKhachSanContext())
                {
                    //Nếu hóa đơn đã tồn tại và chưa thanh toán thì cộng dồn thành tiền
                    try
                    {
                        var hddv = Find(hd => hd.MaKH.Equals(obj.MaKH) && obj.TrangThai.Equals("Chưa Thanh Toán")).Result;
                        if (hddv != null)
                        {
                            var ctHoaDon = new ChiTietHoaDonDVManager();
                            foreach (var ct in obj.ChiTietHoaDonDichVus)
                            {
                                ct.MaHoaDonDV = hddv[0].MaHoaDonDV;
                                ctHoaDon.Add(ct);
                            }
                        }
                    }
                    catch
                    {
                        context.HoaDonDichVus.Add(obj);
                    }
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                acResultl.Exceptions.Add(ex);
            }
            return acResultl;
        }

        public ActionResultAsList<HoaDonDichVu> Find(Expression<Func<HoaDonDichVu, bool>> predicate){
            var acResult = new ActionResultAsList<HoaDonDichVu>();
            try
            {
                var context = new QLKhachSanContext();
                acResult.Result = context.HoaDonDichVus.Where(predicate).ToList();
                if (!acResult.Result.Any())
                {
                    acResult.Exceptions.Add(new Exception("Không tìm thấy hóa đơn dịch vụ nào"));
                    return null;
                }
                return acResult;
            }
            catch (Exception ex)
            {
                acResult.Exceptions.Add(ex);
                return null;
            }
        }

        public ActionResultAsList<HoaDonDichVu> GetListOrderServices()
        {
            var actionResultAsList = new ActionResultAsList<HoaDonDichVu>();
            try
            {
                var context = new QLKhachSanContext();
                actionResultAsList.Result = context.HoaDonDichVus.ToList();
                return actionResultAsList;
            }
            catch (Exception)
            {
                return null;
            }
        }
    }
}
